#include <types.h>
#include <block/block.h>
#include <malloc.h>
#include <uaccess.h>

static block_t *user_bdev = NULL;

u64_t sys_block_read(u8_t *buf, u64_t offset, u64_t count)
{
    // virtio block cannot read data to user's buf directly.
    u8_t *kernel_buf = calloc(1, count);
    u64_t len = block_read(user_bdev, kernel_buf, offset, count);
    copy_to_user(buf, kernel_buf, len);
    free(kernel_buf);
    return len;
}

u64_t sys_block_write(u8_t *buf, u64_t offset, u64_t count)
{
    // virtio block cannot write data from user's buf directly.
    u8_t *kernel_buf = calloc(1, count);
    copy_from_user(kernel_buf, buf, count);
    u64_t len = block_write(user_bdev, kernel_buf, offset, count);
    free(kernel_buf);
    return len;
}

u64_t sys_block_capacity()
{
    return block_capacity(user_bdev);
}

u64_t sys_block_size()
{
    return block_size(user_bdev);
}

u64_t sys_block_count()
{
    return block_count(user_bdev);
}

void do_user_block_init(const char *dev)
{
    user_bdev = search_device_with_class(block_t, dev);
}